home *** CD-ROM | disk | FTP | other *** search
- /* wind.c */
-
- /* JOVE/MSDOS. K. Mitchum 1/85 */
- /* Modifications for personal use only. */
- /* original code J. Payne LSRHS 5/83 */
- /* Ken Mitchum */
- /* University of Pittsburgh */
- /* Decision Systems Laboratory */
-
- /* This creates/deletes/divides/grows/shrinks windows. */
-
- #include "jove.h"
- #include "term.h"
- #include "screen.h"
-
-
- static char onlyone[] = "You only have one window, twit!";
- static char toosmall[] = "too small";
-
-
- /* First line in a window */
-
- FLine(w)
- WINDOW *w;
- {
- WINDOW *wp = fwind;
- int lineno = -1;
-
- do {
- if (wp == w)
- return lineno + 1;
- lineno += wp->w_height;
- wp = wp->w_next;
- } while (wp != fwind);
- complain("WINDOW?");
- /* NOTREACHED */
- }
-
- initwinds(b)
- BUFFER *b;
- {
- WINDOW *wp = fwind;
-
- do {
- if (wp->w_bufp == b) {
- SetTop(wp, (wp->w_line = b->b_dot));
- zero_wind(wp);
- }
- wp = wp->w_next;
- } while (wp != fwind);
- }
-
- /* Return last window on the screen */
-
- WINDOW *
- lastwind()
- {
- WINDOW *wp = fwind;
-
- do {
- if (wp->w_next == fwind)
- return wp;
- wp = wp->w_next;
- } while (wp != fwind);
- /* NOTREACHED */
- }
-
- WINDOW *
-
- getwind()
- {
- WINDOW *wp;
-
- wp = (WINDOW *)emalloc(sizeof (WINDOW));
- return wp;
- }
-
- /* Delete `wp' from the screen. If it is the only window left
- * on the screen, then complain via error. It gives its body
- * to the next window if there is one, otherwise the previous
- * window gets the body. Resets link list and fwind if necessary.
- */
-
- del_wind(wp)
- WINDOW *wp;
- {
- WINDOW *last = lastwind(),
- *prev = wp->w_prev;
-
- if (wp->w_next == wp)
- complain(onlyone);
-
- wp->w_prev->w_next = wp->w_next;
- wp->w_next->w_prev = wp->w_prev;
-
- if (fwind == wp) {
- fwind = wp->w_next;
- fwind->w_height += wp->w_height;
- } else if (wp == last)
- last->w_prev->w_height += wp->w_height;
- else
- prev->w_height += wp->w_height;
- if (curwind == wp)
- SetWind(prev);
- free((char *) wp);
- }
-
- /* Divide the `wp'. Complains if `wp' is too small to be split.
- * It returns the new window
- */
-
- WINDOW *
- div_wind(wp)
- WINDOW *wp;
- {
- WINDOW *new;
-
- if (wp->w_height < 4)
- complain(toosmall);
-
- new = getwind();
- new->w_offset = 0;
- new->w_numlines = 0;
- /* Reset the window bounds */
- new->w_height = (wp->w_height / 2);
- wp->w_height -= new->w_height;
-
- /* Set the lines such that w_line is the center in each window */
- new->w_line = wp->w_line;
- new->w_bufp = wp->w_bufp;
- new->w_top = prev_line(new->w_line, HALF(new));
-
- /* Link the new window into the list */
- new->w_prev = wp;
- new->w_next = wp->w_next;
- new->w_next->w_prev = new;
- wp->w_next = new;
- return new;
- }
-
- /* Return one window previous to `wp'. If at the first window
- * on screen, then go to the last window
- */
-
- WINDOW *
- prev_wind(wp)
- WINDOW *wp;
- {
- return wp->w_prev;
- }
-
- /* Next window from `wp' */
-
- WINDOW *
- next_wind(wp)
- WINDOW *wp;
- {
- return wp->w_next;
- }
-
- /* Initialze the first window setting the bounds to the size of the
- * screen. There is no buffer with this window. See parse for the
- * setting of this window.
- */
-
- winit()
- {
- curwind = fwind = getwind();
-
- curwind->w_line = curwind->w_top = (LINE *) 0;
- curwind->w_char = 0;
- curwind->w_next = curwind->w_prev = fwind;
- curwind->w_height = LI - 1;
- }
-
- /* Change window into the previous window. curwind becomes the new
- * window
- */
-
- PrevWindow()
- {
- WINDOW *new = prev_wind(curwind);
-
- if (new == curwind)
- complain(onlyone);
- SetWind(new);
- }
-
- /* Make new the current window */
-
- SetWind(new)
- WINDOW *new;
- {
- if (new == curwind)
- return;
- curwind->w_line = curline;
- curwind->w_char = curchar;
- curwind->w_bufp = curbuf;
- SetBuf(new->w_bufp);
- if (!inlist(new->w_bufp->b_zero, new->w_line)) {
- new->w_line = curline;
- new->w_char = curchar;
- }
- DotTo(new->w_line, new->w_char);
- if (curchar > strlen(linebuf))
- new->w_char = curchar = strlen(linebuf);
- curwind = new;
- }
-
- /* Delete the current window if it isn't the only one left */
-
- DelCurWindow()
- {
- del_wind(curwind);
- }
-
- /* Return the number of windows being displayed right now */
-
- numwindows()
- {
- WINDOW *wp = fwind;
- int num = 0;
-
- do {
- num++;
- wp = wp->w_next;
- } while (wp != fwind);
- return num;
- }
-
- WindFind()
- {
- char *fname = ask((char *) 0, FuncName());
- BUFFER *buf;
-
- if (buf = file_exists(fname))
- pop_wind(buf->b_name, 0);
- else {
- if (numwindows() == 1)
- curwind = div_wind(curwind);
- else
- curwind = next_wind(curwind);
- SetBuf(do_find(curwind, fname));
- }
- }
-
- /* Go into one window mode by deleting all the other windows */
-
- OneWindow()
- {
- while (curwind->w_next != curwind)
- del_wind(curwind->w_next);
- }
-
- /* Look for a window containing a buffer whose name is `name' */
-
- WINDOW *
- windlook(name)
- char *name;
- {
- BUFFER *bp = (BUFFER *) buf_exists(name);
- WINDOW *wp = fwind;
-
- if (bp == 0)
- return 0;
- do {
- if (wp->w_bufp == bp)
- return wp;
- wp = wp->w_next;
- } while (wp != fwind);
- return 0;
- }
-
- /* Change window into the next window. curwind becomes the new
- * window
- */
-
- NextWindow()
- {
- WINDOW *new = next_wind(curwind);
-
- if (new == curwind)
- complain(onlyone);
- SetWind(new);
- }
-
- /* Scroll the next window */
-
- PageNWind()
- {
- if (numwindows() == 1)
- complain(onlyone);
- NextWindow();
- NextPage();
- PrevWindow();
- }
-
- /* Put a window with the buffer `name' in it. Erase the buffer if
- * `clobber' is non-zero.
- */
-
- pop_wind(name, clobber)
- char *name;
- {
- WINDOW *wp;
- BUFFER *newb;
-
- if ((wp = windlook(name)) == 0) {
- if (numwindows() == 1)
- SplitWind();
- else
- PrevWindow();
- } else
- SetWind(wp);
-
- newb = do_select((WINDOW *) 0, name);
- if (clobber)
- initlist(newb);
- tiewind(curwind, newb);
- SetBuf(newb);
- }
-
- GrowWindow()
- {
- WindSize(curwind, abs(exp));
- }
-
- ShrWindow()
- {
- WindSize(curwind, -abs(exp));
- }
-
- /* Change the size of the window by inc. First arg is the window,
- * second is the increment.
- */
-
- WindSize(w, inc)
- register WINDOW *w;
- {
- if (numwindows() == 1)
- complain(onlyone);
-
- if (inc < 0) { /* Shrinking this window */
- if (w->w_height + inc < 2)
- complain(toosmall);
- w->w_height += inc;
- w->w_prev->w_height -= inc;
- } else
- WindSize(w->w_next, -inc);
- }
-
- /* Set the topline of the window, calculating its number in the buffer.
- * This is for numbering the lines only.
- */
-
- SetTop(w, line)
- WINDOW *w;
- register LINE *line;
- {
- register LINE *lp = w->w_bufp->b_zero;
- register int num = 0;
-
- w->w_top = line;
- if (w->w_numlines)
- while (lp) {
- num++;
- if (line == lp)
- break;
- lp = lp->l_next;
- }
- w->w_topnum = num;
- }
-
- WNumLines()
- {
- zero_wind(curwind);
- /* So the redisplay will know to update the screen even if it
- * looks like there are no differences.
- */
-
- curwind->w_numlines = !curwind->w_numlines;
- SetTop(curwind, curwind->w_top);
- }
-
- zero_wind(wp)
- register WINDOW *wp;
- {
- register int i,
- upper;
-
- upper = FLine(wp);
- for (i = 0; i < wp->w_height; i++)
- oimage[upper + i].Line = (LINE *) -1;
- }
-
- /* Return the line number that `line' occupies in `windes' */
-
- in_window(windes, line)
- register WINDOW *windes;
- register LINE *line;
- {
- register int i;
- LINE *top = windes->w_top;
-
- for (i = 0; top && i < windes->w_height - 1; i++, top = top->l_next)
- if (top == line)
- return FLine(windes) + i;
- return -1;
- }
-
-
-
- /*--------------------------o.s. dependent------------------------*/
-
- abs(i)
- int i;
- {
- if(i >= 0) return i;
- else return(-i);
- }
-
-
-
-
-